package org.example.java8.stream;

import java.util.Optional;

/**
 * 详细请了解java泛型的类型推导机制
 * Optional.empty()生成的对象的泛型需要依靠代码上下文进行推断
 * 比如你的Optional<Test> c = Optional.empty()就给编译器提供了Test的类型信息。
 * 而后面的(Optional<Test>)Optional.empty()因为编译器无法推导出更具体的类型，
 * 所以这里的Optio  nal.empty()是Optional<Object>类型的，而不同类型的泛型对象是不能强转的
 */
public class OptionalUsage {

    public static void main(String[] args) {
        Optional<Insurance> insuranceOptional = Optional.<Insurance>empty();
        //insuranceOptional.get();

        //Objects.requireNonNull(value);
        Optional<Insurance> insuranceOptional1 = Optional.of(new Insurance());
        insuranceOptional1.get();

        Optional<Insurance> objectOptional = Optional.ofNullable(null);
        objectOptional.orElseGet(Insurance::new);
        objectOptional.orElse(new Insurance());
        //objectOptional.orElseThrow(RuntimeException::new);
        //objectOptional.orElseThrow(() -> new RuntimeException("Not have reference"));

        //Insurance insurance = insuranceOptional1.filter(i -> i.getName() != null).get();
        //System.out.println(insurance);

        Optional<String> nameOptional = insuranceOptional1.map(i -> i.getName());
        System.out.println(nameOptional.orElse("empty Value"));
        System.out.println(nameOptional.isPresent());
        nameOptional.ifPresent(System.out::println);

        System.out.println(getInsuranceName(null));
        System.out.println(getInsuranceNameByOptional(null));

    }

    private static String getInsuranceName(Insurance insurance) {
        if (null == insurance)
            return "UNKNOWN";
        return insurance.getName();
    }

    private static String getInsuranceNameByOptional(Insurance insurance) {
        //of不能给null，ofNullable可以给null
        return Optional.ofNullable(insurance).map(Insurance::getName).orElse("unknown");

    }
}
